package com.zvezda.disply.utils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.net.URI;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.CoreConnectionPNames;

import android.app.ActivityManager;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.TransitionDrawable;
import android.media.ThumbnailUtils;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ImageView.ScaleType;

import com.zvezda.android.utils.BitmapUtils;
import com.zvezda.http.utils.HttpConst;

/**
 * 显示图片管理
 * 
 * @author Administrator
 *
 */
public class DisplayManager
{
	/**
	 * 硬盘缓存大小
	 */
	private static final int DISK_CACHE_SIZE = 1024 * 1024 * 100;
	
	/**
	 * 缓存图片的路径
	 */
	private static final String DISK_CACHE_SUBDIR = "thumbnails";
	
	/**
	 * 硬盘缓存
	 */
	private LruDiskCache diskCache = null;
	
	/**
	 * 内存缓存
	 */
	private static LruMemoryCache<String, Bitmap> memoryCache = null;
	
	/**
	 * 加载显示信息的队列
	 */
	private Queue<DisplayConfig> loadDispyConfigQueue = new LinkedList<DisplayConfig>();
	
	/**
	 * 下载显示信息的队列
	 */
	private Queue<DisplayConfig> downLoadDispyConfigQueue = new LinkedList<DisplayConfig>();
	
	/**
	 * 正在下载的显示map
	 */
	private HashMap<String, DisplayConfig> downLoadIngHashMap = new HashMap<String, DisplayConfig>();
	
	/**
	 * 刷新句柄
	 */
	private UpdateHandler updateHandler = null;
	
	/**
	 * 线程池
	 */
	private ExecutorService executorService = null;
	
	/**
	 * 上下文
	 */
	private static Context context = null;
	
	/**
	 * 对象实例
	 */
	private static DisplayManager instance = null;
	
	/**
	 * 获得实例对象
	 * 
	 * @return
	 */
	public static DisplayManager getInstance()
	{
		if (instance == null)
		{
			instance = new DisplayManager();
		}
		return instance;
	}
	
	/**
	 * 初始化加载的东西
	 * 
	 * @param context
	 */
	public void open(Context context)
	{
		DisplayManager.context = context;
		updateHandler = new UpdateHandler(context);
		if (executorService == null)
		{
			// Runtime.getRuntime().availableProcessors();
			executorService = Executors.newFixedThreadPool(5);
		}
		if (memoryCache == null)
		{
			int memClass = ((ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE)).getMemoryClass();
			// 使用可用内存的1/5作为图片缓存
			final int cacheSize = (int) (1024 * 1024 * memClass / 5.0f);
			memoryCache = new LruMemoryCache<String, Bitmap>(cacheSize);
		}
		if (diskCache == null)
		{
			File cacheDir = LruDiskCache.getDiskCacheDir(context, DISK_CACHE_SUBDIR);
			diskCache = LruDiskCache.openCache(context, cacheDir, DISK_CACHE_SIZE);
		}
	}
	
	/**
	 * 关闭显示管理
	 */
	public void close()
	{
		if (loadDispyConfigQueue != null)
		{
			loadDispyConfigQueue.clear();
		}
		if (downLoadDispyConfigQueue != null)
		{
			downLoadDispyConfigQueue.clear();
		}
		if (memoryCache != null)
		{
			memoryCache.evictAll();
		}
		if (diskCache != null)
		{
			diskCache.clearCache();
		}
		if (executorService != null)
		{
			executorService.shutdown();
		}
		if (downLoadIngHashMap != null)
		{
			downLoadIngHashMap.clear();
		}
		updateHandler = null;
		loadDispyConfigQueue = null;
		downLoadDispyConfigQueue = null;
		downLoadIngHashMap = null;
		memoryCache = null;
		diskCache = null;
		executorService = null;
		context = null;
		instance = null;
		System.gc();
	}
	
	/**
	 * 适用于显示列表(有滚动的列表)
	 * 
	 * @param scrollState
	 *            滚动状态
	 * @param displyConfig
	 *            图片信息
	 */
	public void display(int scrollState, DisplayConfig displyConfig)
	{
		if (displyConfig == null || displyConfig.imageView == null || displyConfig.path == null
				|| displyConfig.path.equals(""))
		{
			return;
		}
		if (displyConfig.defaultRes != -1)
		{
			displyConfig.imageView.setImageResource(displyConfig.defaultRes);
		}
		Bitmap bitmap = null;
		// 从内存缓存加载
		if (memoryCache != null)
		{
			bitmap = memoryCache.get("w" + displyConfig.w + "h" + displyConfig.h + displyConfig.path);
		}
		if (bitmap != null)
		{
			displyConfig.isAlpha = false;
			setImageBitmap(displyConfig, bitmap);
			return;
		}
		// 加入显示队列
		displyConfig.imageView.setTag("w" + displyConfig.w + "h" + displyConfig.h + displyConfig.path);
		// 列表停止滚动的时候再请求
		if (scrollState == OnScrollListener.SCROLL_STATE_IDLE)
		{
			addLoadDisplyConfig(displyConfig);
		}
	}
	
	/**
	 * 适用于视图显示(无滚动)
	 * 
	 * @param imageInfo
	 */
	public void display(DisplayConfig displyConfig)
	{
		display(OnScrollListener.SCROLL_STATE_IDLE, displyConfig);
	}
	
	/**
	 * 添加正在下载的图片
	 * 
	 * @param displyConfig
	 */
	private void addDownLoadIngDispyConfig(DisplayConfig displyConfig)
	{
		synchronized (downLoadIngHashMap)
		{
			downLoadIngHashMap.put(displyConfig.url, displyConfig);
		}
	}
	
	/**
	 * 删除正在下载的图片
	 * 
	 * @param displyConfig
	 */
	private void delDownLoadIngDispyConfig(DisplayConfig displyConfig)
	{
		synchronized (downLoadIngHashMap)
		{
			downLoadIngHashMap.remove(displyConfig.url);
		}
	}
	
	/**
	 * 监测是否正在下载
	 * 
	 * @param displyConfig
	 * @return
	 */
	private boolean isHaveDownLoadIng(DisplayConfig displyConfig)
	{
		boolean isHave = false;
		synchronized (downLoadIngHashMap)
		{
			if (downLoadIngHashMap.get(displyConfig.url) != null)
			{
				isHave = true;
			}
		}
		return isHave;
	}
	
	/**
	 * 把需要下载的图片入队列
	 * 
	 * @param displyConfig
	 */
	private void addDownLoadDisplyConfig(DisplayConfig displyConfig)
	{
		synchronized (downLoadDispyConfigQueue)
		{
			Iterator<DisplayConfig> iterator = downLoadDispyConfigQueue.iterator();
			while (iterator.hasNext())
			{
				if (iterator.next().path.equals(displyConfig.path))
				{
					iterator.remove();
				}
			}
			downLoadDispyConfigQueue.add(displyConfig);
			HashMap<String, DisplayConfig> hashMap = new HashMap<String, DisplayConfig>();
			while (downLoadDispyConfigQueue.size() > 0)
			{
				DisplayConfig downLoadDisplyConfig = downLoadDispyConfigQueue.remove();
				hashMap.put(displyConfig.url, downLoadDisplyConfig);
			}
			Iterator<String> iterator2 = hashMap.keySet().iterator();
			while (iterator2.hasNext())
			{
				DisplayConfig downLoadImageInfo = hashMap.get(iterator2.next());
				if (downLoadImageInfo.url != null && !downLoadImageInfo.url.equals(""))
				{
					executorService.execute(new DownLoadRunnable(downLoadImageInfo));
				}
			}
		}
	}
	
	/**
	 * 负责下载图片的线程
	 * 
	 * @author Administrator
	 * 
	 */
	private class DownLoadRunnable implements Runnable
	{
		/**
		 * 显示信息
		 */
		private DisplayConfig displyConfig = null;
		
		/**
		 * 构造函数
		 * 
		 * @param displyConfig
		 */
		public DownLoadRunnable(DisplayConfig displyConfig)
		{
			this.displyConfig = displyConfig;
		}
		
		@Override
		public void run()
		{
			if (!isHaveDownLoadIng(displyConfig))
			{
				addDownLoadIngDispyConfig(displyConfig);
				downLoadDispyConfig(displyConfig);
			}
			else
			{
				addLoadDisplyConfig(displyConfig);
			}
			delDownLoadIngDispyConfig(displyConfig);
		}
		
		/**
		 * HttpClient下载图片
		 * 
		 * @param displyConfig
		 */
		private void downLoadDispyConfig(DisplayConfig displyConfig)
		{
			if (displyConfig == null || displyConfig.path == null || displyConfig.path.equals("")
					|| displyConfig.url == null || displyConfig.url.equals(""))
			{
				return;
			}
			String imagePath = displyConfig.path;
			String imageUrl = displyConfig.url;
			try
			{
				if (!new File(imagePath).createNewFile())
				{
					return;
				}
				URI encodedUri = null;
				HttpGet httpGet = null;
				encodedUri = new URI(imageUrl);
				httpGet = new HttpGet(encodedUri);
				HttpClient httpClient = new DefaultHttpClient();
				// 请求超时
				httpClient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 10000);
				// 读取超时
				httpClient.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, 10000);
				HttpResponse httpResponse = null;
				// 执行请求
				httpResponse = httpClient.execute(httpGet);
				// 请求数据
				HttpEntity httpEntity = httpResponse.getEntity();
				
				if (HttpStatus.SC_OK == httpResponse.getStatusLine().getStatusCode())
				{
					if (httpEntity != null)
					{
						InputStream is = httpEntity.getContent();
						FileOutputStream fos = new FileOutputStream(imagePath);
						byte[] buffer = new byte[1024];
						int len = 0;
						while ((len = is.read(buffer)) != -1)
						{
							fos.write(buffer, 0, len);
						}
						fos.close();
						is.close();
						addLoadDisplyConfig(displyConfig);
					}
				}
				else
				{
					delBadFile(imagePath);
					Log.e(HttpConst.HTTP_LOG, imageUrl);
					Log.e(HttpConst.HTTP_LOG, "获得图片异常-------------->" + httpResponse.getStatusLine().getStatusCode());
				}
			}
			catch (Exception e)
			{
				delBadFile(imagePath);
				Log.e(HttpConst.HTTP_LOG, imageUrl);
				Log.e(HttpConst.HTTP_LOG, "下载图片异常-------------->" + e.toString());
			}
		}
		
		/**
		 * 删除坏文件
		 * 
		 * @param filePath
		 */
		private void delBadFile(String filePath)
		{
			File file = new File(filePath);
			if (file.exists())
			{
				if (file.length() == 0)
				{
					file.delete();
				}
			}
		}
	}
	
	/**
	 * 把要加载的图片入队列
	 * 
	 * @param displyConfig
	 */
	private void addLoadDisplyConfig(DisplayConfig displyConfig)
	{
		synchronized (loadDispyConfigQueue)
		{
			Iterator<DisplayConfig> iterator = loadDispyConfigQueue.iterator();
			while (iterator.hasNext())
			{
				if (iterator.next().path.equals(displyConfig.path))
				{
					iterator.remove();
				}
			}
			loadDispyConfigQueue.add(displyConfig);
			while (loadDispyConfigQueue.size() > 0)
			{
				DisplayConfig loadDisplyConfig = loadDispyConfigQueue.remove();
				if (loadDisplyConfig.path != null && !loadDisplyConfig.path.equals(""))
				{
					executorService.execute(new LoadRunnable(loadDisplyConfig));
				}
			}
		}
	}
	
	/**
	 * 负责加载图片的线程
	 */
	private class LoadRunnable implements Runnable
	{
		/**
		 * 图片信息
		 */
		private DisplayConfig displyConfig = null;
		
		/**
		 * 构造函数
		 * 
		 * @param displyConfig
		 */
		public LoadRunnable(DisplayConfig displyConfig)
		{
			this.displyConfig = displyConfig;
		}
		
		@Override
		public void run()
		{
			loadDispyConfig(displyConfig);
		}
		
		/**
		 * 加载图片
		 * 
		 * @param displyConfig
		 */
		private void loadDispyConfig(DisplayConfig displyConfig)
		{
			if (displyConfig == null || displyConfig.path == null || displyConfig.path.equals("") || displyConfig.w <= 0
					|| displyConfig.h <= 0)
			{
				return;
			}
			Bitmap bitmap = null;
			// 从磁盘缓存加载
			bitmap = diskCache.get("w" + displyConfig.w + "h" + displyConfig.h + displyConfig.path);
			if (bitmap == null)
			{
				bitmap = BitmapUtils.decodeSampledBitmapFromFile(displyConfig.path, displyConfig.w, displyConfig.h,
						displyConfig.bitmapConfig);
				if (bitmap == null && displyConfig.isDownLoadImage)
				{
					addDownLoadDisplyConfig(displyConfig);
					return;
				}
				switch (displyConfig.zoomModel)
				{
					case DisplayConst.ZOOM_FULL:// 填充缩放
						bitmap = BitmapUtils.getScaledBitmap(bitmap, displyConfig.w, displyConfig.h, ScaleType.MATRIX);
						break;
					case DisplayConst.ZOOM_SCALE:// 比例缩放
						float scaleW = displyConfig.w / (float) bitmap.getWidth();
						float scaleH = displyConfig.h / (float) bitmap.getHeight();
						float scale = scaleW < scaleH ? scaleW : scaleH;
						bitmap = BitmapUtils.getScaledBitmap(bitmap, scale, ScaleType.MATRIX);
						break;
					case DisplayConst.ZOOM_THUMBNAIL:// 缩略图
						bitmap = ThumbnailUtils.extractThumbnail(bitmap, displyConfig.w, displyConfig.h,
								ThumbnailUtils.OPTIONS_RECYCLE_INPUT);
						break;
					default:
						break;
				}
				if (displyConfig.angle > 0)
				{
					bitmap = BitmapUtils.toRoundCorner(bitmap, displyConfig.angle);
				}
				if (bitmap != null)
				{
					// 加入双缓存
					if (memoryCache != null)
					{
						synchronized (memoryCache)
						{
							memoryCache.put("w" + displyConfig.w + "h" + displyConfig.h + displyConfig.path, bitmap);
						}
					}
					if (diskCache != null)
					{
						synchronized (diskCache)
						{
							diskCache.put("w" + displyConfig.w + "h" + displyConfig.h + displyConfig.path, bitmap);
						}
					}
				}
			}
			else
			{
				if (bitmap != null)
				{
					if (memoryCache != null)
					{
						synchronized (memoryCache)
						{
							// 加入内存缓存
							memoryCache.put("w" + displyConfig.w + "h" + displyConfig.h + displyConfig.path, bitmap);
						}
					}
				}
			}
			Message message = updateHandler.obtainMessage(0, displyConfig);
			updateHandler.sendMessage(message);
		}
	};
	
	/**
	 * 自定义handler
	 * 
	 * @author Administrator
	 *
	 */
	private static class UpdateHandler extends Handler
	{
		private WeakReference<Context> mActivity = null;
		
		public UpdateHandler(Context activity)
		{
			mActivity = new WeakReference<Context>(activity);
		}
		
		@Override
		public void handleMessage(Message msg)
		{
			do
			{
				if (mActivity.get() != null)
				{
					if (msg.obj == null || !(msg.obj instanceof DisplayConfig))
					{
						break;
					}
					DisplayConfig imageInfo = (DisplayConfig) msg.obj;
					if (imageInfo.imageView == null || imageInfo.imageView.getTag() == null || imageInfo.path == null)
					{
						break;
					}
					// 非同一ImageView
					if (!("w" + imageInfo.w + "h" + imageInfo.h + imageInfo.path).equals(imageInfo.imageView.getTag()
							.toString()))
					{
						break;
					}
					Bitmap bitmap = memoryCache.get("w" + imageInfo.w + "h" + imageInfo.h + imageInfo.path);
					imageInfo.isAlpha = true;
					setImageBitmap(imageInfo, bitmap);
				}
			}
			while (false);
		}
	};
	
	/**
	 * 添加图片的渐出动画
	 * 
	 * @param displyConfig
	 * @param bitmap
	 */
	private static void setImageBitmap(DisplayConfig displyConfig, Bitmap bitmap)
	{
		if (bitmap == null)
		{
			return;
		}
		if (displyConfig.isAlpha)
		{
			Bitmap previousbitmap = displyConfig.imageView.getDrawingCache();
			if (previousbitmap != null && !previousbitmap.isRecycled())
			{
				previousbitmap.recycle();
			}
			
			final TransitionDrawable td = new TransitionDrawable(new Drawable[]
			{
					new ColorDrawable(android.R.color.transparent), new BitmapDrawable(context.getResources(), bitmap)
			});
			td.setCrossFadeEnabled(true);
			displyConfig.imageView.setImageDrawable(td);
			td.startTransition(500);
		}
		else
		{
			Bitmap previousbitmap = displyConfig.imageView.getDrawingCache();
			if (previousbitmap != null && !previousbitmap.isRecycled())
			{
				previousbitmap.recycle();
			}
			Drawable drawable = new BitmapDrawable(context.getResources(), bitmap);
			displyConfig.imageView.setImageDrawable(drawable);
		}
	}
}
